/**
 * @FilePath     : /src/lgmg_robots/agv_navigation/agv_navigate/include/agvNavigate/timer.h
 * @Description  : 定义定时器任务和定时器类，用于管理和执行定时任务。  
 * @Author       : xiujun.yang
 * @Version      : 1.0.0
 * @LastEditors  : haibo haibo.yang@lgmgim.cn
 * @LastEditTime : 2024-12-19 15:54:46
 * @Copyright (c) 2024 by 临工智能信息科技有限公司, All Rights Reserved. 
**/
#pragma once

#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include "z_types.h"
#include "tools.h"
#include <mutex>
constexpr int NUM_TIMER_TASKS = 10; // Max. number of timer tasks

//////////////////////////////////////////////////////////////////////////////
//   The interface of class "CTimerTask".
class  TimerTask
{
 public:
    // Constructor
    TimerTask() : function_(nullptr), param_(0), enabled_(true), exit_(true),
        timer_counter_(0), timer_multiplier_(1), multiplier_on_target_(true) {}

    // Set function for the timer task
    void SetFunction(void (*function)(DWORD), DWORD param = 0, bool enable = true);

    // Clear the timer task
    void Clear();

    // Enable/Disable the timer task
    void Enable(bool enable = true);

    // Test whether the task exists or not
    bool Exists() const;

    // Test whether the task is enabled
    bool IsEnabled() const;

    // Update multiplier
    void UpdateMultiplier(int multiplier);

    // Update counter
    void UpdateCounter();

    // Initialize the timer counter
    void InitCounter();

    // Run the timer task
    void Run();

    // Check whether the task exit
    bool CheckExit() const;
 private:
    void (*function_)(DWORD);  // Array of task entries
    DWORD param_;              // Function parameter
    bool enabled_;             // Task enabled status
    bool exit_;                // Task exit status
    int timer_counter_;
    int timer_multiplier_;
    bool multiplier_on_target_;
};

//////////////////////////////////////////////////////////////////////////////
//   The interface of class "CTimer".
class  Timer
{
 public:
    // Default constructor
    Timer() : soft_timer_(false), period_(0), kill_timer_thread_(nullptr), 
         timer_thread_dead_(nullptr), high_res_timer_(nullptr), 
         started_(false), event_id_(0) {}

    // The destructor
    ~Timer() {
        if (started_) {
            Stop();
        }
    }

    // Set the timer period
    bool SetPeriod(unsigned int period);

    // Get the current timer cycle
    unsigned int GetPeriod() const { return period_; }

    // Start the timer with the given interrupt cycle and service routine
    bool Start(bool soft_timer = false);

    // Stop the current session
    bool Stop();

    // Enable timer
    void Enable();

    // Disable the timer
    void Disable();

    // Update the timer counter
    void UpdateMultiplier(int task_id, int multiplier);

    // Assign a task for the specified timer task
    bool AssignTask(short task_id, void (*task_routine)(DWORD), DWORD param = 0, bool enable = true);

    // Clear the specified timer task (nTaskID == -1, clear all tasks)
    bool ClearTask(short task_id = -1);

    // Enable the specified timer task
    bool EnableTask(short task_id, bool enable = true);

    // Test whether the task is enabled or not
    bool IsTaskEnabled(short task_id);

    // Reset the timer tick
    // void ResetTick();

    // Get the current tick value
    // ULONG GetTick();

    // Check whether the specified task exit
    bool CheckExit(short task_id) const;

 public:
    bool soft_timer_;                    // Use thread timer instead
    unsigned int period_;                // Current cycle period in ms
    TimerTask tasks_[NUM_TIMER_TASKS];   // Array of timer tasks
    pthread_t thread_;                   // Timer thread
    HANDLE kill_timer_thread_;
    HANDLE timer_thread_dead_;
    std::mutex mutex_;
    DWORD echo_;
    std::mutex function_mutex_;          // Function execution lock  

 private:
    bool SetHighResolutionTimer(unsigned long frequency_ms); // Set high resolution timer
    timer_t high_res_timer_;             // High resolution timer
    bool started_;                       // Timer started status
    unsigned int event_id_;              // Timer event ID
};
